package com.openharmony.filepicker.utils;

import com.openharmony.filepicker.bean.BeanSubscriber;
import com.openharmony.filepicker.bean.FileItemBeanImpl;
import com.openharmony.filepicker.bean.FileNavBeanImpl;
import com.openharmony.filepicker.config.FilePickerConfig;
import com.openharmony.filepicker.config.FilePickerManager;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;

public class FileUtils {

    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");

    public static File getRootFile(Context context) {

        return context.getExternalFilesDir(null);
    }

    /**
     * 获取给定文件对象[rootFile]下的所有文件，生成列表项对象
     */
    public static ArrayList<FileItemBeanImpl> produceListDataSource(
            Context context,
            File rootFile,
            BeanSubscriber beanSubscriber
    ) {
        FilePickerConfig config = FilePickerManager.INSTANCE().getConfig();
        ArrayList<FileItemBeanImpl> listData = new ArrayList<>();
        boolean isDetected = false;
        // 查看是否在根目录上级
        File realRoot = getRootFile(context);
        boolean isInRootParent = rootFile.list() == null
                && !config.isSkipDir()
                && rootFile.getPath() == realRoot.getParentFile().getPath();
        if (isInRootParent) {
            // 如果是文件夹作为可选项时，需要让根目录也作为 item 被点击
            listData.add(
                    new FileItemBeanImpl(
                            realRoot.getName(),
                            realRoot.getPath(),
                            false,
                            null,
                            true,
                            false,
                            beanSubscriber
                    )
            );
            if (config.getSelfFilter() == null) {
                return listData;
            } else {
                return config.getSelfFilter().doFilter(listData);
            }
        }

        if (rootFile.listFiles() == null || rootFile.listFiles().length == 0) {
            return listData;
        }

        for (File file : rootFile.listFiles()) {
            //以符号 . 开头的视为隐藏文件或隐藏文件夹，后面进行过滤
            boolean isHiddenFile = file.getName().startsWith(".");
            if (!config.isShowHiddenFiles() && isHiddenFile) {
                // skip hidden files
                continue;
            }
            if (file.isDirectory()) {
                listData.add(
                        new FileItemBeanImpl(
                                file.getName(),
                                file.getPath(),
                                false,
                                null,
                                true,
                                isHiddenFile,
                                beanSubscriber
                        )
                );
                continue;
            }
            FileItemBeanImpl itemBean = new FileItemBeanImpl(
                    file.getName(),
                    file.getPath(),
                    false,
                    null,
                    false,
                    isHiddenFile,
                    beanSubscriber
            );
            // 如果调用者没有实现文件类型甄别器，则使用的默认甄别器
            config.getDefaultFileDetector().fillFileType(itemBean);
            isDetected = itemBean.getFileType() != null;
            if (config.getDefaultFileDetector().isEnableCustomTypes()
                    && config.isAutoFilter()
                    && !isDetected) {
                // enable auto filter AND using user's custom file type. Filter them.
                continue;
            }
            listData.add(itemBean);
        }

        // 默认字典排序
        // Default sort by alphabet
        listData.sort(new Comparator<FileItemBeanImpl>() {
            @Override
            public int compare(FileItemBeanImpl itemBean, FileItemBeanImpl t1) {
                return itemBean.getFileName().compareTo(t1.getFileName());
            }
        });
        // 将当前列表数据暴露，以供调用者自己处理数据
        // expose data list  to outside caller
        if (config.getSelfFilter() == null) {
            return listData;
        } else {
            return config.getSelfFilter().doFilter(listData);
        }
    }

    /**
     * 为导航栏添加数据，也就是每进入一个文件夹，导航栏的列表就添加一个对象
     * 如果是退回到上层文件夹，则删除后续子目录元素
     */
    public static ArrayList<FileNavBeanImpl> produceNavDataSource(
            ArrayList<FileNavBeanImpl> currentDataSource,
            String nextPath,
            Context context
    ) {
        FilePickerConfig config = FilePickerManager.INSTANCE().getConfig();
        if (currentDataSource.isEmpty()) {

            String dirName = "SD Card";

            if (!(config.getMediaStorageName() == null || config.getMediaStorageName().isEmpty())) {
                dirName = config.getMediaStorageName();
            } else if (!config.getCustomRootPath().isEmpty()) {
                dirName = config.getCustomRootPath();
            }

            currentDataSource.add(
                    new FileNavBeanImpl(
                            dirName,
                            nextPath
                    )
            );
            return currentDataSource;
        }

        for (FileNavBeanImpl data : currentDataSource) {
            // 如果是回到根目录
            if (nextPath == currentDataSource.get(0).getFilePath()) {
                return new ArrayList<>(currentDataSource.subList(0, 1));
            }
            // 如果是回到当前目录（不包含根目录情况）
            // 直接返回
            boolean isCurrent = nextPath == currentDataSource.get(currentDataSource.size() - 1).getFilePath();
            if (isCurrent) {
                return currentDataSource;
            }

            // 如果是回到上层的某一目录(即，当前列表中有该路径)
            // 将列表截取至目标路径元素
            boolean isBackToAbove = nextPath == data.getFilePath();
            if (isBackToAbove) {
                return new ArrayList<>(
                        currentDataSource.subList(
                                0,
                                currentDataSource.indexOf(data) + 1
                        )
                );
            }
        }
        // 循环到此，意味着将是进入子目录
        currentDataSource.add(
                new FileNavBeanImpl(
                        nextPath.substring(nextPath.lastIndexOf("/")+1),
                        nextPath
                )
        );
        return currentDataSource;
    }
}
